#import sys
#sys.path.append(...) # TODO add path
from CalTorque import *
import getopt
import logging
import os
import math
from copy import deepcopy
import smtplib
from email.mime.text import MIMEText
from email.MIMEImage import MIMEImage
from email.MIMEMultipart import MIMEMultipart

"""
Module contains methods that assess the quality of CalTorque runs.

Methods:
    SaveNewFiles(): add new data to database
    CreateDatabase(): generate new database with all available files
    UpdatePlots(): generate plots for new data, update all averages
    SendPlots(): upload plots to day log
    SendWarning(): send warning email to mail list if quality check unsatisfactory
    AddRecipient(): add emails to mailing list
    RemoveRecipient(): remove recipient from mailing list
    GetMailList(): returns array of email addresses in mailing list 
    RunQCheck(): assess quality of run from torque and velocity data
    CheckTorque(): compare run torque to average torque to assess quality
    CheckVelocity(): check that velocity does not exceed quality limits
    BinData(): bin data to 1 cm intervals

"""

def SaveNewFiles(db, dataFolder):
    """Add new files to database
    
    Parameters:
        db (dict): unpickled CalTorque database
        dataFolder (str): path to folder containing excel data files
    
    Returns:
        list of filenames of new files added to database
    """
    newData, keys = GetNewRunsFromFolder(db['data'], dataFolder)
    db['data'] = newData
    db['lastImport'] = keys
    SaveCalTorqueDB(db, 'CalDatabase.pkl')
    return db, keys


def CreateDatabase(dataFolder):
    """Create database
    
    Parameters:
        dataFolder (str): path to folder containing excel data files
    
    Returns:
        list of filenames of files added to database
    """
    ls = os.listdir(dataFolder)
    data_files = []
    for i in ls:
        if i.split('.')[-1] not in ['xlsx', 'xls']: continue
        data_files.append(dataFolder + i)

    dataList = {}
    keys = []
    for file in data_files:
        logging.info(file)
        keys.append(file.split('/')[-1])
        dataList[file.split('/')[-1]] = CalTorque(file)
    # create database structure
    db = {}
    db['data'] = dataList
    db['qual'] = {}
    db['qual']['avgout'] = {}
    db['qual']['avgin'] = {}
    db['qual']['src'] = {}
    db['qual']['months'] = {}
    db['qual']['telescope'] = {}
    db['lastImport'] = keys
    SaveCalTorqueDB(db, 'CalDatabase.pkl')
    return db, keys


def UpdatePlots(db, keys, outdir):
    """Call all CalTorque plotting methods to generate plots.
    
    Parameters:
        db: CalTorque database
        keys (list): Filenames of new runs
        outdir (str): path to folder where plots will be deposited
    """
    t = SourceTube()
    tube = t.GetSourceTube()
    
    # find or create directory for plots
    if not os.path.exists(outdir):
        logging.info("Directory for plots does not exist, creating path: " + outdir)
        os.makedirs(outdir)
    
    if not os.path.exists(outdir + 'plots/'):
        logging.info("Directory for plots does not exist, creating path: " + outdir)
        os.makedirs(outdir)
    
    if not os.path.exists(outdir + 'velocity/'):
        logging.info("Directory for plots does not exist, creating path: " + outdir)
        os.makedirs(outdir)
    
    if not os.path.exists(outdir + 'gaussFitPlots/'):
        logging.info("Directory for plots does not exist, creating path: " + outdir)
        os.makedirs(outdir)
    
    # create plots for new data
    for run in db['data']:
        if run in keys:
            logging.info(run)
            PlotCalTorque(db['data'][run], tube, outdir + 'plots/')
            logging.info("  Saving Torque vs time, position")
            PlotTorquevsVelocity(db['data'][run], outdir + 'velocity/')
            try:
                PlotVelocity(db['data'][run], outdir + 'plots/')
                logging.info("  Saving Velocity vs time")
            except Exception, e:
                logging.info("  Velocity plot was not produced due to bad data. " + str(e)) 
            if db['data'][run].Direction() == 'in' and db['data'][run].Offset() != 0:
                PlotFit(db['data'][run], outdir + 'gaussFitPlots/')
                logging.info("  Saving gaussian fit")
    
    newData = {}
    for run in db['data']:
        if run in keys:
            newData[run] = deepcopy(db['data'][run])
    
    # update other plots
    BINS, MAX_D = 400, 400
    logging.info("Plotting average torque in...")
    db['qual']['avgin'] = PlotAvgTorque(newData, db['qual']['avgin'], "in", BINS, MAX_D, outdir)
    logging.info("Plotting average torque out...")
    db['qual']['avgout'] = PlotAvgTorque(newData, db['qual']['avgout'], "out", BINS, MAX_D, outdir)
    logging.info("Plotting source comparison...")
    db['qual']['src'] = PlotSources(newData, db['qual']['src'], BINS, MAX_D, outdir)
    logging.info("Plotting monthly averages...")
    db['qual']['months'] = PlotMonthlyAvgs(newData, db['qual']['months'], BINS, MAX_D, outdir)
    logging.info("Plotting torque before and after Feb 22, 2013...")
    PlotTelescope(newData, db['qual']['telescope'], BINS, MAX_D, outdir)
    logging.info("Plotting max torque vs date...")
    PlotMaxtvsDate(db['data'], outdir)
    logging.info("Plotting max torque vs velocity...")
    PlotMaxtvsVel(db['data'], BINS, MAX_D, outdir)
    logging.info("Plotting offset vs p0...")
    PlotOffsetvsP0(db['data'], outdir)
    logging.info("Plotting poly-two-gauss fit parameters...")
    PlotParameters(db['data'], outdir)
    
    # allow access to keys of last import
    SaveCalTorqueDB(db, 'CalDatabase.pkl')

def GenAllPlots(outdir):
    """Generate plots for all runs in database
    
    Parameters:
        outdir (str): path to folder where plots will be deposited 
    """
    try: 
        db = OpenCalTorqueDB("CalDatabase.pkl")
    except:
        logging.info("Could not open database.")
        sys.exit(0)
    UpdatePlots(db, [], outdir)

def SendPlots():
    """ Sends plots to day log."""
    # TODO submit plots to day log
    pass

def AddRecipients(recipients): # probs best to use mailing list modifiers from interactive terminal
    """Add email addresses to CalQC mailing list
    
    Parameters:
        recipients (list, str): list of email addresses to add to mailing list
    """
    recipFile = open('mailing_list.txt', 'a')
    #move pointer to end
    for email in recipients:
        recipFile.write(email + "\n")
    recipFile.close()
        
def RemoveRecipient(remove):
    """Remove email addresses from CalQC mailing list
    
    Parameters:
        remove (list, str): addresses to remove from mailing list
    """
    lines = GetMailList()
    recipFile = open('mailing_list_temp.txt', 'w')
    for l in lines:
        if l not in remove:
            recipFile.write(l + "\n")
    os.rename(recipFile.name, 'mailing_list.txt')
    
def GetMailList():
    """Get mailing list to send CalQC warning to from mailing_list.txt file"""
    recipients = []    
    recipFile = open('mailing_list.txt', 'r')
    for line in recipFile.readlines():
        recipients.append(line.rstrip())
    recipFile.close()
    return recipients

def SendWarning(errorDet):
    """Send email alert,
    
    Parameters:
        errorDet (str): details of warning
    """
    
    # need to create an account for CalTorqueQualityControl (this is setup for gmail, so that would be ideal)
    sender = 'caltest41@gmail.com'
    recipients = GetMailList()
    
    # create message
    # store message in text file or pickle?
    # send attached log and plots, but add only filenames in email message?
    msg = MIMEMultipart()
    msg['Subject'] = 'CalTorque Quality Control Report'
    msg['From'] = sender
    msg['To'] = ", ".join(recipients)
    
    # create email message
    message = 'The following runs did not meet set quality control standards:\n\n' + errorDet 
    msg.attach(MIMEText(message))
    
    # attach plots to email
    path = 'QCtest/Test1/' # folder name TEMPORARY
    for file in os.listdir(path):
        if file.split('.')[-1] == 'png' and file.split('.')[0].split('w')[0] in errorDet: # TODO fix conditions
            png = open(path + file, 'r')
            img = MIMEImage(png.read())
            png.close()
            msg.attach(img)
    
    # send message
    localHost = 'smtp.gmail.com'
    portNo = 587
    s = smtplib.SMTP(localHost, portNo)
    s.ehlo()
    s.starttls()
    s.ehlo()
    s.login('caltest41@gmail.com', 'TestMail')
    s.sendmail(sender, recipients, msg.as_string())
    s.quit()

def CheckTorque(run, avg):
    """Compare torque data to average torque to determine if dangerously high torques were reached.
    
    Note: For any given position, if the absolute torque exceeds the standard deviation bounds, torque 
        is considered too high.
        
    Parameters:
        run (CalTorque): individual CalTorque data object
        avg (dict): average torque for all runs
    """
    
    # get average data from database, bin run data
    xAvg = numpy.linspace(0,400,400)
    yAvg_min = avg['torAvg'] - (3*avg['stanDev'])
    yAvg_max = avg['torAvg'] + (3*avg['stanDev'])
    xAvg_bin, yAvg_max_bin = Bin(xAvg, yAvg_max, 2)
    xAvg_bin, yAvg_min_bin = Bin(xAvg, yAvg_min, 2)
    xData, yData = Bin(run.NewPosition(), run.Torque(), 2)
    
    errorCount = 0
    error = ""
    # check to see if torque greater than 2 stan dev at that position
    for i, t in enumerate(yData):
        tError = False
        if run.Direction() == 'in' and t > yAvg_max_bin[i]:
            tError = True
        elif run.Direction() == 'out' and t < yAvg_min_bin[i]:
            tError = True
        if tError:
            errorCount += 1
            error = error + """Torque reached exceeds safety limits. Details:
            Run: %s
            High Torque: %f
            Position: around %f cm from parked\n"""%(run, t, xAvg[i])
    if errorCount >= 50:
        ### TEMPORARY
        """
        fig = PLT.figure(figsize = (15, 8), dpi = 150)
        box = [0.14, 0.14, 0.76, 0.76]
        ax = fig.add_axes(box)
        ax.set_ylabel('Position (cm)', color = 'blue')
        ax.set_xlabel('Time (s)')
        PLT.title('QC Test')
        ax.plot(xAvg, avg['torAvg'] - avg['stanDev'], color = 'b', label = 'Standard Deviation')
        ax.plot(xAvg, avg['torAvg'] + avg['stanDev'], color = 'b')
        ax.plot(xData, yData, color = 'black', label = "Torque versus Position data")
        ax.plot(xAvg_bin, yAvg_max_bin, '-', color = 'red', label = "3x Standard deviation")
        ax.plot(xAvg_bin, yAvg_min_bin, '-', color = 'red')
        h, l = ax.get_legend_handles_labels()
        ax.legend(h, l, 'upper left')
        fig.savefig('QCtest/' + run.Filename() + '.png')
        PLT.close()
        return error
        """
    return ""
    # Error message is a bit useless - maybe just send plots, or send "analysis" as log
    
def CheckVelocity(run):
    """ Determine if the velocity of a run is dangerously high
    
    Note: If velocity exceeds 1 rev / 4s, the velocity is considered unsafe. 
    
    Parameters:
        run (CalTorque): individual CalTorque data object
    """
    error = ""
    SPROCKET = 2 #in
    ALLOW_ANGVEL = (2 * math.pi / 4) # 1 rev/4s = Pi/2 rad/s
    ALLOW_VEL = ALLOW_ANGVEL * SPROCKET * 2.54 # 7.98 cm/s
    #ALLOW_VEL = 11.97 #TEMPORARY
    for i, v in enumerate(run.Velocity()):
        if abs(v) > ALLOW_VEL:
            error = error + """Velocity reached exceeds safety limits. Details:
            Velocity: %f cm/s
            Position of occurence: %f cm from parked\n"""%(v, run.NewPosition()[i])
    return error

def RunQCheck(db, keys, email):
    """ Check new CalTorque torque and velocity data for abnormalities potentially indicating 
    improper deployment. If abnormalities are found, send email alerts.
    
    Parameters:
        db (dict): unpickled CalTorque database
        keys (list, str): filenames of runs to check
        email (boolean): if False, warning email will not be sent
        
    """
    f = open('QCtest/Log.txt', 'w')
    f2 = open('QCtest/problems.txt', 'w')
    # check data for problems
    error = ""
    data = db['data']
    avg = db['qual']
    count = 0
    count2 = 0
    for run in data:
        if run in keys:
            if data[run].Direction() != 'in': continue #TEMPORARY
            count += 1
            tError = CheckTorque(data[run], avg['avg' + data[run].Direction()])
            vError = CheckVelocity(data[run])
            if vError != "":#tError != "" or vError != "": # TEMPORARY
                count2 += 1
                r = "Warning for run " + str(data[run]) + "\n"
                error = error + r #+ tError + vError + "\n\n"
                f.write(error)
                f.write("\n")
                f2.write(run + "\n")
    f2.write(str(count2) + "\n")
    f2.write(str(count) + "\n")
    f.close()
    f2.close()
    problem = False
    if error != "":
        problem = True
    
    if problem and email:
        #SendWarning(error)
        return True
    else:
        return False
        
def usage():
    print """Usage: CalQC.py [option]=[arg]
    
Options and Arguments:
    
-h          : print usage
--help      : print usage
-v          : increase output verbosity, must be first after CalQC.py
--verbose   : increase output verbosity, must be first after CalQC.py
--test      : Execute Quality Control check without sending warning email if 
              problem is found, or uploading plots to day log.
--genall    : Generate plots of all runs in database. Program terminates once
              plots are done
--newdb     : create new database with all available data. Note: will run the quality 
              check on entire new database unless --test added as command arg
--datadir=arg: change directory in which excel data files are located. Default
              is 'data/'
              arg: str, path to folder holding data files
--addrecipient=arg: add recipients to quality control mailing list
              arg: str, email addresses to add to list 
              (e.g. ="email@domain.com" 'email2@domain2.com')
--rmrecipient=arg: remove recipients to quality control mailing list
              arg: list of str, email addresses to remove from list
              (e.g. ="email@domain.com" 'email2@domain2.com')
"""

def main(argv = sys.argv):
    """
    
    Constants: 
    These determine manner of execution of the script.
    They can be modified using command line arguments described in usage.
        newDB       - default: False
                      if True, creates a new database with all available data
        
        notTest     - default: True
                      if False, script is run without sending warning emails, or updating plots 
                      to day log
        
        dataFolder  - default: data/
                      path to folder containing excel data files
                      
        keys        - list of new files added to database
        
    """
    
    options = "hv"
    longOptions = ["help", "test", "genall", "newdb", "datadir=", "verbose", "addrecipient=", "rmrecipient="]
    
    # constants
    newDB = False
    notTest = True
    runHist = False #TEMPORARY
    dataFolder = "data/"
    keys = []
    destination = "CalPlots/"
    # parse command line args
    if len(sys.argv) > 1:
        try:
            opts, args = getopt.getopt(argv[1:], options, longOptions)
        except getopt.GetoptError as error:
            print str(error)
            usage()
            sys.exit(0)
        for opt, arg in opts:
            if opt in ("-h", "--help"):
                usage()
                sys.exit(0)
            if opt in ["--verbose", "-v"]:
                logging.basicConfig(level = logging.INFO)
            if opt == "--test":
                notTest = False
            if opt == "--newdb":
                newDB = True
            if opt == "--datadir":
                dataFolder = arg
            if opt == "--genall":
                logging.info("Generating all plots...")
                GenAllPlots(destination)
                logging.info("Plots complete")
                sys.exit(0)
            if opt == "--addrecipient":
                AddRecipients(arg.split(' '))
                logging.info("Added recipient(s) to mailing list. Current list: %s"%str(GetMailList()))
            if opt == "--rmrecipient":
                RemoveRecipient(arg.split(' '))
                logging.info("Removed recipient(s) from mailing list. Current list: %s"%str(GetMailList()))

    # Update run history
    if runHist: # TEMPORARY
        try:
            logging.info("Updating run history...")
            rh = RunHistory()
            rh.UpdateRunHistory()
        except:
            logging.info("Failed to update run history.")
    
    # create or update database
    if newDB:
        logging.info("Creating CalDatabase...")
        db, keys = CreateDatabase(dataFolder)
        try:
            import CalManualChanges
            CalManualChanges.MakeChanges()
        except:
            pass # TEMPORARY
        logging.info("Database complete.")
    else:
        try: 
            # add new files to database
            db = OpenCalTorqueDB("CalDatabase.pkl")
            logging.info("Adding new files to database...")
            db, keys = SaveNewFiles(db, dataFolder)
            logging.info("Added %d new files to database."%len(keys))
        except:
            # if database does not exist, create it
            logging.info("No existing database. Creating CalDatabase...")
            db, keys = CreateDatabase(dataFolder)
            logging.info("Database complete.")
    
    # if keys of new data not empty update plots
    if any(keys):
        logging.info("Generating plots...")
        UpdatePlots(db, keys, destination)
        logging.info("Plots complete")
    
    # temporary
    keys = ['Live Graph 01-Apr-2013_in.xls', 'Live Graph 01-Apr-2013_out.xls', 'Live Graph 01-Dec-2012_in.xls', 'Live Graph 01-Dec-2012_out.xls', 'Live Graph 01-Dec-2013_in.xls', 'Live Graph 01-Dec-2013_out.xls', 'Live Graph 01-Feb-2013_in.xls', 'Live Graph 01-Jan-2013_in.xls', 'Live Graph 01-Jan-2013_out.xls', 'Live Graph 01-Jul-2013_in.xls', 'Live Graph 01-Jul-2013_out.xls', 'Live Graph 01-Jun-2013_in.xls', 'Live Graph 01-Jun-2013_out.xls', 'Live Graph 01-May-2013_in.xls', 'Live Graph 01-May-2013_out.xls', 'Live Graph 01-Nov-2013_sTh_S14+10cm_to_S17+10cm.xls', 'Live Graph 01-Nov-2013_sTh_S8+10cm_to_S14+10cm.xls', 'Live Graph 01-Sep-2013_in.xls', 'Live Graph 01-Sep-2013_out.xls', 'Live Graph 02-Aug-2013_in.xls', 'Live Graph 02-Aug-2013_out.xls', 'Live Graph 02-Dec-2013_in.xls', 'Live Graph 02-Dec-2013_out.xls', 'Live Graph 02-Jan-2013_in.xls', 'Live Graph 02-Jan-2013_out.xls', 'Live Graph 02-Nov-2012_in.xlsx', 'Live Graph 02-Nov-2012_out.xlsx', 'Live Graph 02-Nov-2013_S11+10cm-to-S8+10cm.xls', 'Live Graph 02-Nov-2013_sTh-S17+10cm-to-S11+10cm.xls', 'Live Graph 02-Oct-2013_in.xls', 'Live Graph 03-Apr-2013_in.xls', 'Live Graph 03-Dec-2012_in.xls', 'Live Graph 03-Dec-2012_out.xls', 'Live Graph 03-Dec-2013_in.xls', 'Live Graph 03-Dec-2013_out.xls', 'Live Graph 03-Jan-2013_in.xls', 'Live Graph 03-Jan-2013_out.xls', 'Live Graph 03-Jul-2013_in.xls', 'Live Graph 03-Jul-2013_out.xls', 'Live Graph 03-Jun-2013_out.xls', 'Live Graph 03-May-2013_in.xls', 'Live Graph 03-May-2013_out.xls', 'Live Graph 03-Nov-2013_in.xls', 'Live Graph 03-Nov-2013_out.xls', 'Live Graph 03-Nov-2013_S8+10cm-out.xls', 'Live Graph 04-Dec-2013_in.xls', 'Live Graph 04-Dec-2013_out.xls', 'Live Graph 04-Feb-2013_in.xls', 'Live Graph 04-Feb-2013_out.xls', 'Live Graph 04-Jan-2013_in.xls', 'Live Graph 04-Jan-2013_out.xls', 'Live Graph 04-Sep-2013_in.xls', 'Live Graph 05-Apr-2013_in.xls', 'Live Graph 05-Apr-2013_out.xls', 'Live Graph 05-Aug-2013_in.xls', 'Live Graph 05-Aug-2013_out.xls', 'Live Graph 05-Dec-2012_in.xls', 'Live Graph 05-Dec-2012_out.xls', 'Live Graph 05-Dec-2013_in.xls', 'Live Graph 05-Dec-2013_out.xls', 'Live Graph 05-Jul-2013_in.xls', 'Live Graph 05-Jul-2013_out.xls', 'Live Graph 05-Jun-2013_in.xls', 'Live Graph 05-Jun-2013_out.xls', 'Live Graph 05-Mar-2013_inwkThplus6.xls', 'Live Graph 05-Mar-2013_outwkThminus4.xls', 'Live Graph 05-May-2013_in.xls', 'Live Graph 05-Nov-2012_in.xlsx', 'Live Graph 05-Nov-2012_out.xlsx', 'Live Graph 05-Oct-2013_in.xls', 'Live Graph 05-Oct-2013_out.xls', 'Live Graph 05-Sep-2013_in.xls', 'Live Graph 05-Sep-2013_out.xls', 'Live Graph 05-Sep-2013_out2.xls', 'Live Graph 06-Feb-2013_in.xls', 'Live Graph 06-Feb-2013_out.xls', 'Live Graph 06-Mar-2013_in_ThS5plus2.xls', 'Live Graph 06-Mar-2013_out_ThS5minus4.xls', 'Live Graph 06-May-2013_out.xls', 'Live Graph 06-Sep-2013_in.xls', 'Live Graph 06-Sep-2013_out.xls', 'Live Graph 07-Aug-2013_in.xls', 'Live Graph 07-Aug-2013_out.xls', 'Live Graph 07-Dec-2012_in.xls', 'Live Graph 07-Dec-2012_out.xls', 'Live Graph 07-Dec-2013_in.xls', 'Live Graph 07-Dec-2013_out.xls', 'Live Graph 07-Feb-2013_in.xls', 'Live Graph 07-Feb-2013_out.xls', 'Live Graph 07-Jan-2012_out.xls', 'Live Graph 07-Jan-2013_in.xls', 'Live Graph 07-Jan-2013_out.xls', 'Live Graph 07-Jun-2013_in.xls', 'Live Graph 07-Jun-2013_out.xls', 'Live Graph 07-May-2013_in.xls', 'Live Graph 07-May-2013_out.xls', 'Live Graph 07-Nov-2012_in.xlsx', 'Live Graph 07-Nov-2012_out.xlsx', 'Live Graph 07-Oct-2013_in.xls', 'Live Graph 07-Oct-2013_out.xls', 'Live Graph 08-Apr-2013_in.xls', 'Live Graph 08-Apr-2013_out.xls', 'Live Graph 08-Feb-2013_in.xls', 'Live Graph 08-Feb-2013_out.xls', 'Live Graph 08-Jul-2013_in.xls', 'Live Graph 08-Jul-2013_in_S5oldtoS5new.xls', 'Live Graph 08-Jul-2013_out.xls', 'Live Graph 08-Mar-2013_in.xls', 'Live Graph 08-Mar-2013_out.xls', 'Live Graph 08-May-2013_in.xls', 'Live Graph 08-May-2013_out.xls', 'Live Graph 08-Nov-2013_in.xls', 'Live Graph 08-Nov-2013_out.xls', 'Live Graph 09-Dec-2013_in.xls', 'Live Graph 09-Dec-2013_out.xls', 'Live Graph 09-Feb-2013_in.xls', 'Live Graph 09-Feb-2013_out.xls', 'Live Graph 09-Jun-2013_out.xls', 'Live Graph 09-May-2013_in.xls', 'Live Graph 09-May-2013_out.xls', 'Live Graph 09-Nov-2012_in.xlsx', 'Live Graph 09-Nov-2012_out.xlsx', 'Live Graph 09-Oct-2013_in.xls', 'Live Graph 09-Oct-2013_out.xls', 'Live Graph 09-Sep-2013_in.xls', 'Live Graph 09-Sep-2013_out.xls', 'Live Graph 1-Apr-2013_in.xls', 'Live Graph 1-Apr-2013_out.xls', 'Live Graph 10-Apr-2013_in.xls', 'Live Graph 10-Apr-2013_out.xls', 'Live Graph 10-Dec-2012_in.xls', 'Live Graph 10-Dec-2012_out.xls', 'Live Graph 10-Jan-2013_in_test.xls', 'Live Graph 10-Jan-2013_out_test.xls', 'Live Graph 10-Jul-2013_in.xls', 'Live Graph 10-Jul-2013_out.xls', 'Live Graph 10-Jun-2013_in.xls', 'Live Graph 10-Jun-2013_out.xls', 'Live Graph 10-May-2013_in.xls', 'Live Graph 10-May-2013_out.xls', 'Live Graph 10-Sep-2013_in.xls', 'Live Graph 10-Sep-2013_out.xls', 'Live Graph 11-Feb-2013_in.xls', 'Live Graph 11-Feb-2013_out.xls', 'Live Graph 11-Jan-2013_in.xls', 'Live Graph 11-Jan-2013_out.xls', 'Live Graph 11-Mar-2013_in.xls', 'Live Graph 11-Mar-2013_out.xls', 'Live Graph 11-May-2013_in.xls', 'Live Graph 11-May-2013_out.xls', 'Live Graph 11-Oct-2013_out.xls', 'Live Graph 12-Apr-2013_in.xls', 'Live Graph 12-Apr-2013_out.xls', 'Live Graph 12-Aug-2013_in.xls', 'Live Graph 12-Dec-2012_in.xls', 'Live Graph 12-Dec-2012_out.xls', 'Live Graph 12-Jan-2013_in.xls', 'Live Graph 12-Jan-2013_out.xls', 'Live Graph 12-Jul-2013_in.xls', 'Live Graph 12-Jul-2013_out.xls', 'Live Graph 12-Jun-2013_?in.xls', 'Live Graph 12-Jun-2013_?out.xls', 'Live Graph 12-May-2013_out.xls', 'Live Graph 12-May-2013_S11n1905.xls', 'Live Graph 12-May-2013_S11n730.xls', 'Live Graph 12-May-2013_S11p0.xls', 'Live Graph 12-May-2013_S11p667.xls', 'Live Graph 12-May-2013_S8n1548.xls', 'Live Graph 12-May-2013_S8p0.xls', 'Live Graph 12-May-2013_S8p1746.xls', 'Live Graph 12-May-2013_S8p793.xls', 'Live Graph 12-Sep-2013_in.xls', 'Live Graph 13-Aug-2013_out.xls', 'Live Graph 13-Dec-2013_in.xls', 'Live Graph 13-Dec-2013_out.xls', 'Live Graph 13-Jan-2013_in.xls', 'Live Graph 13-Jan-2013_out.xls', 'Live Graph 13-Mar-2013_in.xls', 'Live Graph 13-Mar-2013_out.xls', 'Live Graph 13-May-2013_inS2.xls', 'Live Graph 13-May-2013_inS5.xls', 'Live Graph 13-May-2013_retractS2.xls', 'Live Graph 13-Nov-2012_in.xlsx', 'Live Graph 13-Nov-2012_out.xlsx', 'Live Graph 13-Sep-2013_out.xls', 'Live Graph 14-Aug-2013_in.xls', 'Live Graph 14-Aug-2013_out.xls', 'Live Graph 14-Dec-2012_in.xls', 'Live Graph 14-Dec-2012_out.xls', 'Live Graph 14-Jan-2013_in.xls', 'Live Graph 14-Jan-2013_out.xls', 'Live Graph 14-Jun-2013_in.xls', 'Live Graph 14-Jun-2013_out.xls', 'Live Graph 14-May-2013_inS5.xls', 'Live Graph 14-May-2013_outS2.xls', 'Live Graph 14-May-2013_outS5.xls', 'Live Graph 14-Nov-2012_in.xlsx', 'Live Graph 14-Nov-2012_out.xlsx', 'Live Graph 14-Oct-2013_in.xls', 'Live Graph 14-Oct-2013_out.xls', 'Live Graph 15-Apr-2013_in.xls', 'Live Graph 15-Apr-2013_out.xls', 'Live Graph 15-Aug-2013_in.xls', 'Live Graph 15-Aug-2013_out.xls', 'Live Graph 15-Feb-2013_in.xls', 'Live Graph 15-Feb-2013_out.xls', 'Live Graph 15-Jan-2013_in.xls', 'Live Graph 15-Jan-2013_out.xls', 'Live Graph 15-Jul-2013_out.xls', 'Live Graph 15-Mar-2013_in.xls', 'Live Graph 15-Mar-2013_out.xls', 'Live Graph 15-May-2013_inS11p953.xls', 'Live Graph 15-May-2013_inS8.xls', 'Live Graph 15-May-2013_out.xls', 'Live Graph 15-May-2013_outS11n445.xls', 'Live Graph 15-May-2013_outS11p254.xls', 'Live Graph 15-Nov-2012_in.xlsx', 'Live Graph 15-Nov-2012_out.xlsx', 'Live Graph 16-Aug-2013_in.xls', 'Live Graph 16-Aug-2013_out.xls', 'Live Graph 16-Dec-2013_in.xls', 'Live Graph 16-Dec-2013_out.xls', 'Live Graph 16-Jan-2013_in.xls', 'Live Graph 16-Jan-2013_out.xls', 'Live Graph 16-May-2013_inCsS5.xls', 'Live Graph 16-May-2013_outCsS5.xls', 'Live Graph 16-May-2013_wThBrian.xls', 'Live Graph 16-Oct-2013_in.xls', 'Live Graph 16-Oct-2013_out.xls', 'Live Graph 16-Sep-2013_in.xls', 'Live Graph 16-Sep-2013_out.xls', 'Live Graph 17-Apr-2013_in.xls', 'Live Graph 17-Apr-2013_out.xls', 'Live Graph 17-Aug-2013_in.xls', 'Live Graph 17-Aug-2013_out.xls', 'Live Graph 17-Dec-2012_in.xls', 'Live Graph 17-Dec-2012_out.xls', 'Live Graph 17-Dec-2013_in.xls', 'Live Graph 17-Dec-2013_out.xls', 'Live Graph 17-Jan-2013_in.xls', 'Live Graph 17-Jan-2013_out.xls', 'Live Graph 17-May-2013_in.xls', 'Live Graph 17-May-2013_out.xls', 'Live Graph 17-Nov-2012_out.xlsx', 'Live Graph 18-Feb-2013_in.xls', 'Live Graph 18-Feb-2013_out.xls', 'Live Graph 18-Jan-2013_out.xls', 'Live Graph 18-Jul-2013_in.xls', 'Live Graph 18-Jul-2013_out.xls', 'Live Graph 18-Jun-2013_wRa_in.xls', 'Live Graph 18-Mar-2013_in.xls', 'Live Graph 18-Nov-2013-out.xls', 'Live Graph 18-Nov-2013_in.xls', 'Live Graph 18-Oct-2013_out.xls', 'Live Graph 18-Sep-2013_in.xls', 'Live Graph 18-Sep-2013_out.xls', 'Live Graph 19-Apr-2013_in.xls', 'Live Graph 19-Apr-2013_out.xls', 'Live Graph 19-Aug-2013_in.xls', 'Live Graph 19-Aug-2013_out.xls', 'Live Graph 19-Dec-2012_in.xls', 'Live Graph 19-Dec-2012_out.xls', 'Live Graph 19-Dec-2013_in.xls', 'Live Graph 19-Dec-2013_out.xls', 'Live Graph 19-Feb-2013_inS11.xls', 'Live Graph 19-Feb-2013_inS8.xls', 'Live Graph 19-Feb-2013_out.xls', 'Live Graph 19-Feb-2013_outS11_to_mod2.xls', 'Live Graph 19-Jul-2013_in.xls', 'Live Graph 19-Jul-2013_out.xls', 'Live Graph 19-Jun-2013_wRaS2_in.xls', 'Live Graph 19-Jun-2013_wRaS5_in.xls', 'Live Graph 19-Nov-2012_in.xlsx', 'Live Graph 19-Nov-2012_out.xlsx', 'Live Graph 2-Jan-2014_in.xls', 'Live Graph 2-Jan-2014_out.xls', 'Live Graph 20-Dec-2013_out.xls', 'Live Graph 20-Feb-2013_inS5_Cs.xls', 'Live Graph 20-Feb-2013_out_Cs.xls', 'Live Graph 20-Jul-2013_in.xls', 'Live Graph 20-Jul-2013_out.xls', 'Live Graph 20-Jun-2013_wCsS5_in.xls', 'Live Graph 20-Jun-2013_wCsS5_out.xls', 'Live Graph 20-Jun-2013_wRaS5_out.xls', 'Live Graph 20-Mar-2012_?.xlsx', 'Live Graph 20-Mar-2013_in.xls', 'Live Graph 20-Mar-2013_out.xls', 'Live Graph 20-May-2013_in.xls', 'Live Graph 20-May-2013_out.xls', 'Live Graph 20-Sep-2013_in.xls', 'Live Graph 20-Sep-2013_out.xls', 'Live Graph 21-Aug-2013_in.xls', 'Live Graph 21-Aug-2013_out.xls', 'Live Graph 21-Dec-2012_in.xls', 'Live Graph 21-Dec-2012_out.xls', 'Live Graph 21-Feb-2013_inS11_Co.xls', 'Live Graph 21-Feb-2013_inS8_Co.xls', 'Live Graph 21-Feb-2013_out_Co.xls', 'Live Graph 21-Feb-2013_outS5_Co.xls', 'Live Graph 21-Jan-2013_in.xls', 'Live Graph 21-Jan-2013_out.xls', 'Live Graph 21-Jun-2013_wCoS5_in.xls', 'Live Graph 21-Nov-2012_in.xlsx', 'Live Graph 21-Nov-2012_out.xlsx', 'Live Graph 21-Nov-2013_out.xls', 'Live Graph 21-Oct-2013_out.xls', 'Live Graph 22-Apr-2013_in.xls', 'Live Graph 22-Apr-2013_out.xls', 'Live Graph 22-Jul-2013_in.xls', 'Live Graph 22-Jul-2013_out.xls', 'Live Graph 22-Jun-2013_in.xls', 'Live Graph 22-Jun-2013_wCoS5_out.xls', 'Live Graph 22-May-2013_out.xls', 'Live Graph 22-Nov-2013_in.xls', 'Live Graph 22-Nov-2013_out.xls', 'Live Graph 23-Aug-2013_in.xls', 'Live Graph 23-Aug-2013_out.xls', 'Live Graph 23-Dec-2012_in.xls', 'Live Graph 23-Dec-2012_out.xls', 'Live Graph 23-Dec-2013_in.xls', 'Live Graph 23-Dec-2013_out.xls', 'Live Graph 23-Jun-2013_out.xls', 'Live Graph 23-Mar-2013_in.xls', 'Live Graph 23-Mar-2013_out.xls', 'Live Graph 23-Nov-2013_in.xls', 'Live Graph 23-Nov-2013_out.xls', 'Live Graph 23-Oct-2013_out.xls', 'Live Graph 23-Sep-2013_in.xls', 'Live Graph 23-Sep-2013_out.xls', 'Live Graph 24-Apr-2013_in.xls', 'Live Graph 24-Apr-2013_out.xls', 'Live Graph 24-Jan-2013_in.xls', 'Live Graph 24-Jan-2013_out.xls', 'Live Graph 24-Jan-2014_in.xls', 'Live Graph 24-Jan-2014_out.xls', 'Live Graph 24-Jul-2013_in.xls', 'Live Graph 24-Jul-2013_out.xls', 'Live Graph 24-Jun-2013_in.xls', 'Live Graph 24-Jun-2013_out.xls', 'Live Graph 24-May-2013_in.xls', 'Live Graph 24-May-2013_out.xls', 'Live Graph 25-Apr-2013_in.xls', 'Live Graph 25-Apr-2013_out.xls', 'Live Graph 25-Jan-2013_in.xls', 'Live Graph 25-Jan-2013_out.xls', 'Live Graph 25-Mar-2013_in.xls', 'Live Graph 25-Mar-2013_out.xls', 'Live Graph 25-Nov-2013_in.xls', 'Live Graph 25-Nov-2013_out.xls', 'Live Graph 25-Sep-2013_in.xls', 'Live Graph 25-Sep-2013_out.xls', 'Live Graph 26-Apr-2013_in.xls', 'Live Graph 26-Apr-2013_out.xls', 'Live Graph 26-Aug-2013_in.xls', 'Live Graph 26-Aug-2013_out.xls', 'Live Graph 26-Dec-2012_2_in.xls', 'Live Graph 26-Dec-2012_2_out.xls', 'Live Graph 26-Dec-2012_in.xls', 'Live Graph 26-Dec-2012_out.xls', 'Live Graph 26-Dec-2013_in.xls', 'Live Graph 26-Jan-2013_in.xls', 'Live Graph 26-Jan-2013_out.xls', 'Live Graph 26-Jun-2013_in.xls', 'Live Graph 26-Jun-2013_out.xls', 'Live Graph 26-Nov-2013_in.xls', 'Live Graph 26-Nov-2013_out.xls', 'Live Graph 26-Oct-2013-test.xls', 'Live Graph 27-Apr-2013_in.xls', 'Live Graph 27-Apr-2013_out.xls', 'Live Graph 27-Aug-2013_in.xls', 'Live Graph 27-Aug-2013_out.xls', 'Live Graph 27-Dec-2012_in.xls', 'Live Graph 27-Dec-2012_out.xls', 'Live Graph 27-Dec-2013_in.xls', 'Live Graph 27-Dec-2013_out.xls', 'Live Graph 27-Jul-2013_in.xls', 'Live Graph 27-Jul-2013_out.xls', 'Live Graph 27-Nov-2013_in.xls', 'Live Graph 27-Nov-2013_out.xls', 'Live Graph 27-Sep-2013_in.xls', 'Live Graph 27-Sep-2013_out.xls', 'Live Graph 28-Aug-2013_in.xls', 'Live Graph 28-Aug-2013_out.xls', 'Live Graph 28-Dec-2012_in.xls', 'Live Graph 28-Dec-2012_out.xls', 'Live Graph 28-Dec-2013_in.xls', 'Live Graph 28-Dec-2013_out.xls', 'Live Graph 28-Jan-2013_in.xls', 'Live Graph 28-Jan-2013_out.xls', 'Live Graph 28-Jun-2013_in.xls', 'Live Graph 28-Jun-2013_out.xls', 'Live Graph 28-Jun-2013_retractS2.xls', 'Live Graph 28-May-2013_inS5.xls', 'Live Graph 28-May-2013_outS5.xls', 'Live Graph 28-Oct-2013_in.xls', 'Live Graph 28-Oct-2013_in_S2_to_S5_Ra226.xls', 'Live Graph 28-Oct-2013_out.xls', 'Live Graph 28-Oct-2013_Ra226_in.xls', 'Live Graph 29-Apr-2013_out.xls', 'Live Graph 29-Dec-2013_in.xls', 'Live Graph 29-Dec-2013_out.xls', 'Live Graph 29-Jul-2013_in.xls', 'Live Graph 29-Jul-2013_out.xls', 'Live Graph 29-Jun-2013_in.xls', 'Live Graph 29-Jun-2013_out.xls', 'Live Graph 29-May-2013_inS5.xls', 'Live Graph 29-May-2013_out_toS2-10cm.xls', 'Live Graph 29-Oct-2013-S8-to-S5+1inch.xls', 'Live Graph 29-Oct-2013_Move-from-S5-toS8.xls', 'Live Graph 29-Oct-2013_S8-to-S5+1inch.xls', 'Live Graph 30-Aug-2013_in.xls', 'Live Graph 30-Aug-2013_out.xls', 'Live Graph 30-Jan-2013_in.xls', 'Live Graph 30-Jan-2013_out.xls', 'Live Graph 30-Mar-2013_in.xls', 'Live Graph 30-Mar-2013_out.xls', 'Live Graph 30-May-2013_in.xls', 'Live Graph 30-May-2013_out.xls', 'Live Graph 30-Nov-2012_in.xls', 'Live Graph 30-Nov-2012_out.xls', 'Live Graph 30-Nov-2013_in.xls', 'Live Graph 30-Nov-2013_out.xls', 'Live Graph 30-Oct-2013-in-to-S5+1inch-137Cs.xls', 'Live Graph 30-Oct-2013_s2_out.xls', 'Live Graph 30-Oct-2013_S5+1inch-Cs_out.xls', 'Live Graph 30-Oct-2013_S5+1inch-to-S2_Ra.xls', 'Live Graph 30-Sep-2013_in.xls', 'Live Graph 30-Sep-2013_out.xls', 'Live Graph 31-Dec-2013_out.xls', 'Live Graph 31-Jul-2013_in.xls', 'Live Graph 31-Jul-2013_out.xls', 'Live Graph 31-May-2013_in.xls', 'Live Graph 31-May-2013_out.xls', 'Live Graph 31-Oct-2012_in.xlsx', 'Live Graph 31-Oct-2012_out.xlsx', 'Live Graph 31-Oct-2013_Co_S5+1in_in.xls', 'Live Graph 31-Oct-2013_Cs-out-from-S5+1inch.xls', 'Live Graph 31-Oct-2013_out_Co-50_from_S5+1inch.xls', 'Live Graph 31-Oct-2013_S5+1inch_in.xls', 'Live Graph 31-Oct-2013_sTh_S8+10cm_in.xls', 'Live Graph 4-Jan-2014_in.xls', 'Live Graph 4-Jan-2014_out.xls']
    
    if notTest:
        logging.info("Submitting plots to day log...")
        SendPlots()
        logging.info("Plots submitted.")
    
    # run quality control check
    logging.info("Performing quality check...")
    rqc = RunQCheck(db, keys, notTest)
    logging.info("Quality check complete.")
    if rqc:
        logging.info("Problem identified. Warning email sent.")
    else:
        logging.info("No problems identified.")
    
if __name__ == "__main__":
   main(sys.argv)